package org.fastframework.mvc;

import org.fastframework.mvc.annotation.PostParam;
import org.fastframework.mvc.annotation.RequestMethod;
import org.fastframework.mvc.bean.HandlerBody;
import org.fastframework.util.ReflectUtil;
import org.fastframework.util.WebUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.List;
import java.util.ArrayList;

/**
 * Handler 调用器
 *
 * Created by bysocket on 16/8/9.
 */
public class HandlerInvoker {

	/**
	 * 请求处理器
	 * 根据请求,获取请求参数
	 * 调用Method,获取返回值
	 * 调用View,返回响应
	 *
	 * @param request
	 * @param response
	 * @param handler
	 */
	public static void invokeHandler(HttpServletRequest request, HttpServletResponse response, HandlerBody handler) {
		List<Object> controllerMethodParamList = new ArrayList<>();
		Method controllerMethod = handler.getControllerMethod();

		// POST 请求
		if (request.getMethod().equals(RequestMethod.POST.toString())) {
			List<Class<?>> getParameterTypes = new ArrayList();
			Class<?> postParamType = null;

			for (Parameter p: controllerMethod.getParameters()) {
				if (p.isAnnotationPresent(PostParam.class)) {
					postParamType = p.getType();
				} else {
					getParameterTypes.add(p.getType());
				}
			}
			controllerMethodParamList = WebUtil.getRequestParamMap(request, getParameterTypes.toArray(new Class<?>[0]));
			Object postParamObject = WebUtil.getRequestBody(request, postParamType);
			controllerMethodParamList.add(0, postParamObject);

		}
		// GET 请求
		else if (request.getMethod().equals(RequestMethod.GET.toString())) {
			// 从 Request 获取参数 - Controller.Method 的 ParamList
			controllerMethodParamList = WebUtil.getRequestParamMap(request, controllerMethod.getParameterTypes());
		}

		// ReflectUtil 获取 Controller.Method 的返回值
		Object controllerMethodResult = ReflectUtil.invokeControllerMethod(handler.getControllerClass(),
				handler.getControllerMethod(),controllerMethodParamList);

		// View 处理
		ViewResolver.resolveView(request,response,controllerMethodResult,handler);
	}

}
